package glossos;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import glossos.tree.Node;

import org.junit.Before;
import org.junit.Test;

public class NodeTestCase {

    @Before
    public void setUp() {
    }

    @Test
    public void testTreeRootAndLeaf() {
        Node root = new Node("foo");
        Node leaf = new Node("bar");
        root.append(leaf);

        assertTrue(root.isRoot());
        assertTrue(leaf.isLeaf());

        assertFalse(leaf.isRoot());
        assertFalse(root.isLeaf());
    }

    @Test
    public void sequenceTailDoesntIncludeStartParameter() throws Exception {
        Node node1 = new Node(1L, "abc", 1);
        Node node2 = new Node(2L, "def", 1);
        Node node3 = new Node(3L, "ghi", 1);
        Node node4 = new Node(4L, "jkl", 1);

        node1.append(node2).append(node3).append(node4);

        assertThat(node4.sequenceTail(node2), is("ghi jkl"));
    }

    @Test
    public void sequenceConcatenatesAllNodeWordsExceptRoot() {
        Node root = new Node(0L, null, 1);
        Node node1 = new Node(1L, "abc", 1);
        Node node2 = new Node(2L, "def", 1);
        Node node3 = new Node(3L, "ghi", 1);
        Node node4 = new Node(4L, "jkl", 1);

        root.append(node1).append(node2).append(node3).append(node4);
        assertThat(node4.sequence(), is("abc def ghi jkl"));
    }

    @Test
    public void appendNonExistingWordSetsItsFrequencyToOne() {
        Node root = new Node("abc");

        Node child1 = root.append(new Node("xyz"));
        assertThat(child1.getFrequency(), is(1));

        Node child2 = root.append(new Node("xyz"));
        assertThat(child2.getFrequency(), is(2));
    }

    @Test
    public void incrementNodeFrequency() {
        Node root = new Node("foo");
        Node bar = new Node("bar", 991);
        Node zee = new Node("zee", 573);

        root.append(bar);
        root.append(zee);
        root.incrementChildFrequency("bar");

        // remember: insertChild already increments node frequency
        assertThat(root.childWithWord("bar").getFrequency(), is(993));
        assertThat(root.childWithWord("zee").getFrequency(), is(574));
    }

    @Test
    public void mostFrequentChild() {
        Node root = new Node("foo");
        Node bar = new Node("bar", 991);
        Node zee = new Node("zee", 573);

        root.append(bar);
        root.append(zee);

        assertThat(root.mostFrequentChild(), is(bar));
    }

    @Test
    public void childWithWord() {
        Node root = new Node("foo");

        root.append(new Node("bar"));

        assertTrue(root.hasChildWithWord("bar"));
        assertFalse(root.hasChildWithWord("idea"));
    }

    @Test
    public void compareFrequecies() {
        Node bar = new Node("bar", 991);
        Node zee = new Node("zee", 573);

        assertTrue(zee.lessFrequentThan(bar));
        assertFalse(bar.lessFrequentThan(zee));
        assertFalse(bar.lessFrequentThan(bar));
    }

    @Test
    public void stringRepresentation() {
        Node bar = new Node("bar", 991);
        bar.setId(12L);
        assertThat(bar.toString(), is("12:bar|991"));
    }
}
